_ = require 'underscore'
CustomApp = require '../db/CustomApp'
ProductApp = require '../db/ProductApp'
certificate = require '../db/Certificate'
fse = require 'fs-extra'
fs = require 'fs'
fsp = require '../bin/libs/fs-promises'
Q = require 'q'
gm = require 'gm'
request = require 'request'
zip = require '../bin/libs/zip'
buildRequest = require '../bin/libs/build-request'

###
  app 定制
  ###
module.exports = (app) ->

    certificate_path = app.get('certificate_path')
    sandbox_path = app.get('sandbox_path')

    app.get '/', (req, res, next) ->
      res.render 'customize', {title: '应用列表', username: req.session.user.username}

    app.get '/apps/:app_id/appdowload', (req,res) ->
      URL_PUZZLE_HTTP = "http://appbuilder.yonyou.com:4080";
      URL_PUZZLE_HTTPS = "https://appbuilder.yonyou.com:4443";
      URL_CA_CER = URL_PUZZLE_HTTP + "/puzzle/ca.cer";
      url = ""
      msginfo= "正在安装，请在桌面查看安装情况"
      buttontext= "下载 app"
      switch req.query.platform
        when "ios"
          url = URL_PUZZLE_HTTPS + '/puzzle/archives/' + req.query.arc + '/install/ios'
        when "android"
          url = URL_PUZZLE_HTTP + '/puzzle/archives/' + req.query.arc + '.apk'
        when "cer"
          buttontext= "证书安装"
          msginfo= "证书安装过程中要求输入手机解锁密码"
          url = URL_CA_CER
      CustomApp.findOne _id: req.params.app_id, (err, obj)->
        if err
          console.log 'app not found'
          obj = {name: "runtime 打包", logo: ""}
        res.render "dowload",{url: url, name : obj.name, logo: "/apps/img/#{obj.id}?t=#{new Date().getTime()}", title: '应用下载', msginfo: msginfo, buttontext: buttontext, layout: false}

    app.get '/apps/img/:app_id', (req,res) ->
      new Promise (resolve, reject) ->
          fix= 'icons/AppIcon29x29.png'
          if (req.query.type == 'sp')
            fix= 'launchImages/LaunchImage-568h@2x.png'
          image = fs.createReadStream("#{sandbox_path}#{req.params.app_id}/images/#{fix}")
          res.writeHead 200, {
              'Content-Type': 'image/png'
          }
          image.pipe(res);

      .catch (err) ->
          console.log err
          res.send('download err')
          res.end()

    #创建定制app
    app.post '/apps', app.uploader.fields([{ name: 'logo', maxCount: 1 }, { name: 'splash', maxCount: 1 }]), (req, res, next) ->
      _app = _.pick(req.body, ['name', 'version', 'user_id', 'platform', 'product_id', 'product_name', 'certificate_id'])
      #未打包状态
      _app.status = 2
      _app.modify_person= req.session.user.username
      new Promise (resolve, reject) ->
        CustomApp.save _app, (err, obj) ->
          return reject(err) if err
          resolve(obj)
      .then (obj) ->
        new Promise (resolve, reject) ->
          _pathIcons= "#{sandbox_path}#{obj.id}/images/icons"
          _pathLaunchImages= "#{sandbox_path}#{obj.id}/images/launchImages"
          Q.all [
            fsp.ensureDir _pathIcons
            fsp.ensureDir _pathLaunchImages
            fsp.ensureDir "#{sandbox_path}#{obj.id}/certificate"
          ]
          .then ->
            # 图片处理
            savePic("logo", req.files['logo'][0], _pathIcons)
            .then ->
              savePic("splash", req.files['splash'][0], _pathLaunchImages)
              .then ->
                # 证书处理
                certificate.findOne _id: obj.certificate_id, (err, cerObj) ->
                  return reject err if err
                  cerpath= "#{certificate_path}#{cerObj.id}/";
                  files = fs.readdirSync cerpath
                  files.forEach (each) ->
                    /\.(.*)$/g.test(each);
                    fsp.copy "#{cerpath}#{each}", "#{sandbox_path}#{obj.id}/certificate/embedded.#{RegExp.$1}"
                    .then ->
                      obj.cer_pw= cerObj.password
                      resolve(obj)
                    .catch (err) ->
                      reject err
          .catch (err) ->
            return reject(err) if err
      .then (data) ->
        # 调用打包
        build(data, res)

      .catch (err) ->
        console.error err
        res.status(404).json {code:-1, message:'add Failed'}

    # 重新打包
    app.post  '/apps/rebuild/:app_id', (req,res) ->
      CustomApp.findOne _id: req.params.app_id, (err, data) ->
        certificate.findOne _id: data.certificate_id, (err, cerObj) ->
          return res.status(404).json {code:-1, message:'Can\'t find apps.'} if err
          data.cer_pw= cerObj.password
          build(data, res)

    # 打包
    build= (data, res) ->
      sandbox_path = app.get('sandbox_path')
      # tempProject 压缩后保存的位置
      app_id = data.id
      pathDir = "#{sandbox_path}#{app_id}"
      zipFile = "#{pathDir}-build.zip"
      pathDirBuild = "#{pathDir}-build"
      #文件重命名操作
      fsp.remove_safe pathDirBuild
      .then ->
        fsp.copy pathDir, pathDirBuild
        .then ->
          console.log '开始zip'
          zip(pathDirBuild, zipFile)
          .then (tempProject) ->
            console.log tempProject
            buildRequest tempProject, {
              platform: data.platform
              bundleIdentifier: data.bundleIdentifier || "com.yonyou.innovation.xxx"
              title: data.name || '企业空间'
              cer_pw: data.cer_pw
              }
            .then (objStr) ->
              obj= JSON.parse objStr
              CustomApp.update _id: data.id , {task_id: obj.id, stateurl: obj.stateurl, down_url: obj.pakurl}, (err, obj) ->
                return res.status(500).json {code: -1, data: data} if err
                res.status(200).json {code: 0, data: data}

      .catch (err) ->
        CustomApp.update _id: data.id , {status: 1}, (err, obj) ->
          console.log obj if err
          res.status(200).json {code: -1, data: data}



    ###*
     * 图片按比例保存处理
     * @param  {[type]} type logo/splash
     * @param  {[type]} file 文件
     * @return {[type]}      [description]
    ###
    savePic= (type, file, path) ->
      gm_img = gm(file.path)
      {
        logo: (type, file)->
          return new Promise (resolve, reject) ->
            gm_img.resize 144, 144, '!'
            _icon= "#{path}/AppIcon60x60@3x.png"
            _icon1= "#{path}/AppIcon60x60@2x.png"
            _icon2= "#{path}/AppIcon57x57.png"
            _icon3= "#{path}/AppIcon57x57@2x.png"
            _icon4= "#{path}/AppIcon40x40@3x.png"
            _icon5= "#{path}/AppIcon40x40@2x.png"
            _icon6= "#{path}/AppIcon29x29@3x.png"
            _icon7= "#{path}/AppIcon29x29@2x.png"
            _icon8= "#{path}/AppIcon29x29.png"
            # _pathIcon144= "#{path}/icon-72.png"
            writeFile gm_img, _icon
            .then ->
              fsp.copy _icon, _icon1
              fsp.copy _icon, _icon2
              fsp.copy _icon, _icon3
              fsp.copy _icon, _icon4
              fsp.copy _icon, _icon5
              fsp.copy _icon, _icon6
              fsp.copy _icon, _icon7
              fsp.copy _icon, _icon8
              resolve()
            .catch (err) ->
              reject(err)
        splash: (type, file) ->
          return new Promise (resolve, reject) ->
            gm_img.resize 452 , 803, '!'
            _452h= "#{path}/LaunchImage-568h@2x.png"
            _452h2= "#{path}/LaunchImage-700-568h@2x.png"

            _451h= "#{path}/LaunchImage-800-667h@2x.png"
            _451h2= "#{path}/LaunchImage-800-Portrait-736h@3x.png"

            _535h= "#{path}/LaunchImage-700@2x.png"
            writeFile gm_img, _452h
            .then ->
              fsp.copy _452h, _452h2
              gm_img.resize 451, 803, '!'
              writeFile gm_img, _451h
              .then ->
                fsp.copy _451h, _451h2
                gm_img.resize 535, 803, '!'
                writeFile gm_img, _535h
                .then ->
                  resolve()
            .catch (err) ->
              reject(err)
      }[type](type, file, path)

    ###*
     * 写文件
     * @param  {[type]} gm_img [description]
     * @param  {[type]} file   [description]
     * @return {[type]}        [description]
    ###
    writeFile= (gm_img, file)->
      new Promise (resolve, reject) ->
        gm_img.write file, (err) ->
          return reject(err) if err
          resolve()


    queryList= (req, res, next) ->
      keyword = req.query.name || ""
      query = {}
      pageSize = parseInt (req.params.limit || 10)
      page = parseInt (req.params.page || 1)

      query['name'] = new RegExp keyword

      new Promise (resolve,reject) ->
        CustomApp.find query
        .sort "-modify_date"
        .limit(pageSize)
        .skip (page - 1 ) * pageSize
        .exec (err, listdata) ->
          return reject(err) if err
          CustomApp.count (err, count) ->
            return reject(err) if err
            res.status(200).json {code:0, data: listdata, total: count}
      .catch (err) ->
          return res.status(404).json {code:-1, message:'Can\'t find apps.'}


    #查询所有定制app
    app.get '/apps', (req, res, next) ->
      queryList(req, res, next)

    #分页查询定制app
    app.get '/apps/:page/:limit', (req, res, next) ->
      queryList(req, res, next)

    #查询定制app by id
    app.get '/apps/:app_id', (req, res, next) ->
      CustomApp.findOne _id: req.params.app_id, (err, data) ->
         return res.status(404).json {code:-1, message:'Can\'t find apps.'} if err
         res.status(200).json {code: 0, data: data}

    #删除定制app by id
    app.delete '/apps/:app_id', (req, res, next) ->
      dir_path = "#{sandbox_path}#{req.params.app_id}"
      new Promise (resolve, reject) ->
        fsp.remove dir_path
        .then ->
          resolve()
        .catch (err) ->
          return reject(err) if err
      .then () ->
        new Promise (resolve, reject) ->
          CustomApp.findOneAndRemove _id: req.params.app_id, (err, obj) ->
            return reject(err) if err
            resolve(obj)
      .then (data) ->
        res.status(200).json {code: 0, data: 'delete successfully'}
      .catch (err) ->
        console.log err
        res.status(404).json {code:-1, message:'delete Failed'}

    #更新定制app by id
    app.put '/apps/:app_id', (req, res, next) ->
      update =  _.pick(req.body, ['name', 'version', 'certificate_id', 'status', 'platform'])
      #使用自己的证书
      if update.certificate_id
        fsp.traverse_safe "#{certificate_path}#{update.certificate_id}"
        .then (result) ->
          console.log result
          all = _.map result, (each) ->
            fsp.copy each, "#{sandbox_path}#{req.params.app_id}/certificate#{each.substring(each.lastIndexOf('/'))}"
          Q.all all
        .then () ->
          console.log 'ok'
      CustomApp.findOneAndUpdate _id: req.params.app_id, update, (err, data) ->
         return res.status(404).json {code:-1, message:'Can\'t find apps.'} if err
         res.status(200).json {code: 0, data: 'update successfully'}
